package cn.com.wangluotongxin.netty.handler;

import cn.com.wangluotongxin.admin.netty.AdminNettyRabbitmqPushService;
import cn.com.wangluotongxin.admin.netty.AdminQueue;
import cn.com.wangluotongxin.admin.netty.pojo.OffLineRequest;
import cn.com.wangluotongxin.netty.cache.LoggerUtil;
import cn.com.wangluotongxin.netty.cache.NettyChannelCacheUtil;
import cn.com.wangluotongxin.netty.event.NettyChannelMessageEvent;
import cn.com.wangluotongxin.netty.pojo.ChannelPojo;
import cn.hutool.core.date.DateUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;


/**
 * Socket拦截器，用于处理客户端的行为
 *
 * @author Gjing
 **/
@Slf4j
@Component
@ChannelHandler.Sharable
public class NettyChannelInfoHandler extends SimpleChannelInboundHandler<WebSocketFrame>{

    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;
    @Autowired
    private AdminNettyRabbitmqPushService adminNettyRabbitmqPushService;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame webSocketFrame) throws Exception {
        LoggerUtil.logger(webSocketFrame.content());
        ByteBuf byteBuf = webSocketFrame.content();
        applicationEventPublisher.publishEvent(new NettyChannelMessageEvent(this, ctx.channel(), byteBuf));
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        String channelId = ctx.channel().id().asLongText();
        log.info("新的客户端链接：" + channelId);
        ChannelPojo pojo = new ChannelPojo()
                .setChannel(ctx.channel());
        NettyChannelCacheUtil.set(channelId, pojo);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        String channelId = ctx.channel().id().asLongText();
        log.info("客户端断开链接：" + channelId);
        NettyChannelCacheUtil.remove(channelId);

        OffLineRequest request = new OffLineRequest()
                .setChannelId(channelId)
                .setDateTime(DateUtil.date());
        adminNettyRabbitmqPushService.push(AdminQueue.ADMIN_NETTY_OFF_LINE, request);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        String channelId = ctx.channel().id().asLongText();
        log.info("客户端连接异常强制断开链接：" + channelId);
        ctx.channel().close();
        NettyChannelCacheUtil.remove(channelId);

        OffLineRequest request = new OffLineRequest()
                .setChannelId(channelId)
                .setDateTime(DateUtil.date());
        adminNettyRabbitmqPushService.push(AdminQueue.ADMIN_NETTY_OFF_LINE, request);
    }
}
